#include "Project.h"
#include <fcntl.h>
#include <errno.h>

int uart2_fd = -1; //存储UART2外设的文件代号

char cmd_test[] = "AT\r\n"; //测试指令
char cmd_change_name[] = "AT+NAMEduoyu\r\n";//更改模块名字为duoyu
char cmd_reset[] = "AT+RESET\r\n";//软重启
char cmd_set_slave_mode[] = "AT+ROLE0\r\n";//设置成从模式
char cmd_find_mode[] = "AT+ROLE\r\n";//查询主模式？从模式？
char recv_buf_blue[128]; //为了接收蓝牙模块的响应信息




void blue_start()
{
    int retry_count = 0;
    const int max_retries = 3;
    
    while (retry_count < max_retries)
    {
        // 1.打开开发板的UART2 防止该串口影响基本串口
        if (uart2_fd != -1) {
            close(uart2_fd); // 关闭之前的文件描述符
        }
        
        uart2_fd = open("/dev/ttySAC2", O_RDWR|O_NOCTTY);
        if (uart2_fd == -1) { 
            printf("uart2文件打开失败: %s\n", strerror(errno));
            retry_count++;
            sleep(1);
            continue;
        }
        
        UART2_Init();                //蓝牙的串口的初始化
        // 2.配置UART2的参数  字符格式 + 通信速率 9600bps

        // 3.响应测试
        tcflush(uart2_fd, TCIOFLUSH); //刷新串口的缓冲区
        write(uart2_fd, cmd_test, strlen(cmd_test)); //发送指令给蓝牙模块
        usleep(100*1000); // 等待响应
        memset(recv_buf_blue, 0, sizeof(recv_buf_blue));
        read(uart2_fd, recv_buf_blue, sizeof(recv_buf_blue)-1); // 读取蓝牙模块的响应信息
        printf("AT测试响应: %s\n", recv_buf_blue);

        // 4.查询主模式？从模式？
        tcflush(uart2_fd, TCIOFLUSH); //刷新串口的缓冲区
        write(uart2_fd, cmd_find_mode, strlen(cmd_find_mode));
        usleep(100*1000); // 等待响应
        memset(recv_buf_blue, 0, sizeof(recv_buf_blue));
        read(uart2_fd, recv_buf_blue, sizeof(recv_buf_blue)-1);
        printf("角色查询响应: %s (0 —> slave dev)\n", recv_buf_blue);
        
        // 检查是否收到正确的响应
        if (strstr(recv_buf_blue, "OK") != NULL) {
            printf("SUCCESS   蓝牙模块响应正常: %s\n", recv_buf_blue);
            read_JPEG_file("success.jpg", 0, 0);
            break;
        } else {
            printf("FAILED   蓝牙模块响应异常: %s\n", recv_buf_blue);
            read_JPEG_file("error.jpg", 0, 0);
            retry_count++;
            continue;
        }

        // 5.修改蓝牙模块的名字
        tcflush(uart2_fd, TCIOFLUSH); //刷新串口的缓冲区
        write(uart2_fd, cmd_change_name, strlen(cmd_change_name));
        usleep(100*1000); // 等待响应
        memset(recv_buf_blue, 0, sizeof(recv_buf_blue));
        read(uart2_fd, recv_buf_blue, sizeof(recv_buf_blue)-1);
        printf("改名响应: %s\n", recv_buf_blue);

        // 6.重启生效
        tcflush(uart2_fd, TCIOFLUSH); //刷新串口的缓冲区
        write(uart2_fd, cmd_reset, strlen(cmd_reset));
        usleep(200*1000); // 等待重启
        break; // 成功完成配置，退出循环
    }
    
    if (retry_count >= max_retries) {
        printf("蓝牙模块初始化失败，已达到最大重试次数\n");
        if (uart2_fd != -1) {
            close(uart2_fd);
            uart2_fd = -1;
        }
        return;
    }


    sleep(2);
    
    // 使用互斥锁保护状态重置
    pthread_mutex_lock(&state_mutex);
    desk = 1;
    teacher_ways_flag = 0;  // == 1 就是老师
    student_ways_flag = 0;  // == 1 就是学生
    stu_atten_flag = 0;     //学生打卡方式   1蓝牙 2刷卡  3人脸  4密码
    tea_atten_flag = 0;     //老师打卡方式   1蓝牙 2刷卡  3人脸  4密码
    again_re_select_flag = 0;//失败了显示
    pthread_mutex_unlock(&state_mutex);
}

// 添加清理函数
void blue_cleanup()
{
    if (uart2_fd != -1) {
        close(uart2_fd);
        uart2_fd = -1;
        printf("蓝牙串口已关闭\n");
    }
}




void UART2_Init()//串口2的初始化
{
    //1.定义两个串口结构体
    struct termios old_attr; //保存串口的旧属性
    struct termios new_attr; //保存串口的新属性

    //2.保存串口的原本的属性
    if (tcgetattr(uart2_fd, &old_attr) == -1) {
        printf("获取串口属性失败: %s\n", strerror(errno));
        return;
    }

    //3.初始化新属性结构体
    memset(&new_attr, 0, sizeof(new_attr));

    //4.配置数据位  8bit
    new_attr.c_cflag &= ~CSIZE; //清空数据位
    new_attr.c_cflag |= CS8;    //8位数据位

    //5.配置停止位  1bit
    new_attr.c_cflag &= ~CSTOPB; //1位停止位

    //6.配置校验位  none
    new_attr.c_cflag &= ~PARENB; //不使用校验位

    //7.配置波特率  9600bps
    if (cfsetospeed(&new_attr, B9600) == -1 || cfsetispeed(&new_attr, B9600) == -1) {
        printf("设置波特率失败: %s\n", strerror(errno));
        return;
    }

    //8.配置本地连接和接收使能
    new_attr.c_cflag |= CREAD | CLOCAL;

    //9.设置等待时间和最少接收字符
    new_attr.c_cc[VTIME] = 0;
    new_attr.c_cc[VMIN] = 1;

    //10.设置为原始模式（指的是所有输入的字符都会被当做普通字符）
    cfmakeraw(&new_attr);

    //11.确保参数生效 （立即）
    if (tcsetattr(uart2_fd, TCSANOW, &new_attr) == -1) {
        printf("设置串口属性失败: %s\n", strerror(errno));
        return;
    }

    //12.清空输入输出缓冲区
    tcflush(uart2_fd, TCIOFLUSH);
    
    printf("UART2初始化成功\n");
}
